import React, {
  FC,
  useContext,
  CSSProperties,
  ReactChild,
  cloneElement,
  ReactNode,
  Children,
  FunctionComponentElement,
  ChangeEvent,
  InputHTMLAttributes,
} from 'react';
import classNames from 'classnames';
import { Row, Col, colTypeProps } from '../gird';
import formContext from './context';
// import { itemType } from './interface';

export interface ruleType {
  required?: boolean;
  message?: string;
}
export interface itemType {
  name?: string;
  label?: string;
  rules?: ruleType[];
  className?: string;
  children?: ReactNode;
  labelCol?: colTypeProps;
  wrapperCol?: colTypeProps;
}

export const item: FC<itemType> = props => {
  const {
    className,
    children,
    name = '',
    label,
    labelCol = {},
    wrapperCol = {},
  } = props;

  // 得到父组件传递的Context
  const { setValue, values } = useContext(formContext);

  const classes = classNames(className);

  const itemChange = (value: any) => {
    // todo 这里有点技巧性的东西了  ,如果 inputItem!.props!.onChange(value); 里面再有操作 setValue 的，就无法保证顺序了，
    // 所以这里就先等setValue执行完毕，然后在调用外部change
    const inputItem = children as any;
    setValue(name, value);
    setTimeout(() => {
      if (inputItem!.props!.onChange) {
        inputItem!.props!.onChange(value);
      }
    }, 1);
  };

  const inputContentRender = () => {
    const inputChildren = children as any; // 这里子节点类型较多
    if (inputChildren!.type!.displayName === 'input') {
      return cloneElement(inputChildren, {
        onChange: (e: ChangeEvent<InputHTMLAttributes<HTMLElement>>) => {
          itemChange(e.target.value || '');
        },
        value: values[name as string],
      });
    }
    return inputChildren;
  };

  return (
    <Row className={classNames('ant-form-item', className)}>
      {label && (
        <Col {...labelCol} className="ant-form-item-label">
          <label
            htmlFor="basic_username"
            className="ant-form-item-required"
            title="Username"
          >
            {label}
          </label>
        </Col>
      )}
      <Col {...wrapperCol} className="ant-form-item-control">
        <div className="ant-form-item-control-input">
          <div className="ant-form-item-control-input-content">
            {inputContentRender()}
          </div>
        </div>
      </Col>
    </Row>
  );
};

item.displayName = 'fromItem';
// item.defaultProps={
//   name:'',
// }
export default item;
